
package org.report.pdf;

// *************************************************************************/
// Charada Soft
// Area de Desarrollo de Sistemas de Información
// *************************************************************************/
// Proyecto : java creator document
// Archivo : DocumentCreator.java
// Descripcion : Clase DocumentCreator
// *************************************************************************/
// Version : 1.0.5
// Fecha de Creación: 11 de Julio de 2014
// Author : Daniel Andres Castillo Pedroza
// *************************************************************************/

import com.lowagie.text.BadElementException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.Barcode128;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import java.awt.Color;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.report.pdf.object.*;

public class DocumentCreator {
    
    // Atributos de la clase DocumentCreator
    
    private DocumentProperties properties;
    private Font font;
    private Document document;
    private PdfWriter writer;
    private int alignmentText = DocumentConstans.LEFT;
    private int alignmentImage = DocumentConstans.CENTER;
    
    @SuppressWarnings("FieldMayBeFinal")
    private float leading = 18f;
    
    // Atributos finales de la clase DocumentCreator
    
    // private final BaseColor NEGRO = DocumentConstans.NEGRO;
    
    // Constructores de la clase DocumentCreator
    
    public DocumentCreator() {
        this(new DocumentProperties());
    }
    
    public DocumentCreator(DocumentProperties properties) {
        initProperties(properties);
    }
    
    // Metodos de la clase DocumentCreator
    
    /**
      * 
      * @param properties 
    */
    
    private void initProperties(DocumentProperties properties) {
        setProperties(properties); setFont(new FontCreator());
    }
    
    /**
      * 
      * @param properties 
    */
    
    public final void setProperties(DocumentProperties properties) {
        if (properties != null) {
            this.properties = properties;
        } // Estableciendo nuevas propiedades
    }
    
    /**
      * 
      * @return
      * @throws FileNotFoundException 
    */
    
    private FileOutputStream createFile() throws FileNotFoundException {
        return new FileOutputStream(properties.getRootFile());
    }
    
    /**
      * 
      * @param properties
      * @return 
    */
    
    private Rectangle createPaper(DocumentProperties properties) {
      // Declarando y configurando Datos para el Proceso
      float widthDocument = properties.getPageDimension().getWidth();
      float heightDocument = properties.getPageDimension().getHeight();
        
      // Creando dimensiones del Documento
      return new Rectangle(widthDocument,heightDocument);
    }
    
    /**
      * 
      * @param object 
    */
    
    private void setMargins(DocumentProperties properties) {
        // Declarando y configurando Datos para el Proceso
        float marginLeft = properties.getPageMargins().getLeft();
        float marginRigth = properties.getPageMargins().getRigth();
        float marginUp = properties.getPageMargins().getTop();
        float marginDown = properties.getPageMargins().getBottom();

        // Estableciendo margenes en el Documento
        document.setMargins(marginLeft,marginRigth,marginUp,marginDown);
    }
    
    /**
      * Este método nos permite crear un documento PDF en la ruta
      * establecida en sus Propiedades. Ademas lo deja abierto para
      * insertar datos de cualquier tipo.
      * @throws FileNotFoundException Se lanzara esta excepción si
      *  la Ruta establecida no existe en el Dispositivo.
      * @throws DocumentException Se lanzara esta excepción si
      *  ocurre un error al tratar de crear y abrir documento.
    */
    
    public void createDocument() throws FileNotFoundException, DocumentException {
        document = new Document(); // Instanciando objeto de Proceso

        // Configurando y creando documento en Ruta establecida
        writer = PdfWriter.getInstance(document,createFile());      
        document.setPageSize(createPaper(properties)); 
        setMargins(properties); // Margenes del Documento
        
        document.open(); // Abriendo documento para Insertar Datos
    }
    
    /**
      * Este método nos permite crear un documento PDF en la ruta
      * establecida en sus Propiedades. Ademas lo deja abierto para
      * insertar datos de cualquier tipo.
      * @param output
      * @throws FileNotFoundException Se lanzara esta excepción si
      *  la Ruta establecida no existe en el Dispositivo.
      * @throws DocumentException Se lanzara esta excepción si
      *  ocurre un error al tratar de crear y abrir documento.
    */
    
    public void createDocument(OutputStream output) throws FileNotFoundException, DocumentException {
        document = new Document(); // Instanciando objeto de Proceso

        // Configurando y creando documento en Ruta establecida
        writer = PdfWriter.getInstance(document,output);
        document.setPageSize(createPaper(properties)); 
        setMargins(properties); // Margenes del Documento
        
        document.open(); // Abriendo documento para Insertar Datos
    }
    
    /**
      * 
      * @param font 
    */
    
    public void setFont(FontCreator font) {
        this.font = font.getFont();
    }
    
    /**
      * 
      * @param alignment 
    */
    
    public void setAlignmentText(int alignment) {
        this.alignmentText = alignment;
    }
    
    /**
      * 
      * @param alignment 
    */
    
    public void setAlignmentImage(int alignment) {
        this.alignmentImage = alignment;
    }
    
    /**
      * Este método nos permite insertar un Parrafo en el Documento. Donde
      * el texto del Parrafo se establece con un objeto <code>String</code>.
      * @param texto Texto a insertar en el Parrafo
    */
    
    public void insertParagraph(String texto) {
        try {
            Paragraph parrafo = new Paragraph(texto,font);
            parrafo.setLeading(leading);
            parrafo.setAlignment(alignmentText); 
            document.add(parrafo); // Insertando Parrafo
        } // Se inserto el Parrafo en el Documento
        
        catch (DocumentException ex) {
            System.err.println(ex.getMessage());
        } // Error al Insertar Parrafo
    }
    
    /**
      * Este método nos permite insertar un Parrafo en el Documento. Donde
      * el texto del Parrafo se establece con un objeto <code>Object</code>.
      * @param object Contiene el texto a insertar en el Parrafo
    */
    
    public void insertParagraph(Object object) {
        insertParagraph(object.toString()); // Insertando Parrafo
    }
    
    /**
      * Este método nos permite insertar una Frase en el Documento. Donde
      * el texto de la Frase se establece con un objeto <code>String</code>.
      * @param texto Texto a insertar en la Frase
    */
    
    public void insertPhrase(String texto) {
        try {
            Phrase frase = new Phrase(texto,font); document.add(frase);
        } // Se inserto la Frase en el Documento
      
        catch (DocumentException ex) {
            System.err.println(ex.getMessage());
        } // Error al Insertar Frase
    }
    
    /**
      * Este método nos permite insertar una Frase en el Documento. Donde
      * el texto de la Frase se establece con un objeto <code>Object</code>.
      * @param object Contiene el texto a insertar en la Frase
    */
    
    public void insertPhrase(Object object) {
        insertPhrase(object.toString()); // Insertando Frase
    }
    
    /**
      * Este método nos permite insertar una Imagen en el Documento.
      * Donde la imagen se establece con un objeto <code>Image</code>.
      * @param imagen Imagen a insertar en el Documento
    */
    
    public void insertImage(Image imagen) {
        try {
            document.add(imagen);
        } // Se insertó la Imagen Correctamente
      
        catch (BadElementException ex) {
            System.err.println(ex.getMessage());
        } // Error al insertar Imagen
        
        catch (DocumentException ex) {
            System.err.println(ex.getMessage());
        } // Error al insertar Imagen
    }
    
    /**
      * Este método nos permite insertar una Tabla en el Documento.
      * Donde la imagen se establece con un objeto <code>PdfPTable</code>.
      * @param table Imagen a insertar en el Documento
    */
    
    public void insertTable(PdfPTable table) {
        try {
            document.add(table);
        } // Se insertó la Tabla Correctamente
        
        catch (DocumentException ex) {
            System.err.println(ex.getMessage());
        } // Error al insertar Tabla
    }
    
    /**
      * 
      * @param codigoBarra 
    */
    
    public void insertBarCode128(String codigoBarra) {
        try {
            // Contenedor del Código de Barras
            PdfContentByte content = writer.getDirectContent();

            // Instanciando y configurando el Código de Barras
            Barcode128 barCode128 = new Barcode128();
            barCode128.setX(1f); barCode128.setN(0.5f);
            barCode128.setChecksumText(true);
            barCode128.setGenerateChecksum(true);
            barCode128.setSize(5f); barCode128.setBaseline(9f);
            barCode128.setTextAlignment(DocumentConstans.CENTER);
            barCode128.setBarHeight(40f); barCode128.setCode(codigoBarra);
        
            // Creando imagen del Código de Barra 
            Image imagen = barCode128.createImageWithBarcode(content,Color.BLACK,Color.BLACK);
            imagen.setAlignment(alignmentImage); document.add(imagen);
        } // Se ha insertado Código de Barras en el Documento
      
        catch (DocumentException ex) {
            System.err.println(ex.getMessage());
        } // Error al insertar Código de Barras
    }
    
    /**
      * 
      * @return 
    */
    
    public boolean newPage() {
        return document.newPage();
    }
    
    /**
      * 
      * @param titulo 
    */
    
    public void setTitle(String titulo) {
        document.addTitle(titulo);      
    }
    
    /**
      * 
      * @param editor 
    */
    
    public void setEditor(String editor) {
        document.addKeywords(editor);
    }
    
    /**
      * 
      * @param sujeto 
    */
    
    public void setSubject(String sujeto) {
        document.addSubject(sujeto);
    }
    
    /**
      * 
      * @param aplicacion 
    */
    
    public void setAplication(String aplicacion) {
        document.addCreator(aplicacion);
    }
    
    /**
      * 
    */
    
    public void closeDocument() {
        document.close(); // Cerrando documento despues de Insertar Datos
    }
}